home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 626-637 / disk_628 / set040 / source / set040.s < prev   
Text File  |  1992-05-06  |  89KB  |  1,811 lines

  1.     COMMENT /          
  2.  
  3. ;This code is Copyright © Nic Wilson 1991, 1992
  4. ;It is supplied here only as an example of programming
  5. ;the 68040 MMU on a fully blown 68040 compatible assembler.
  6. ;such as the one I use, Macro68.
  7. ;
  8. ;I am a dealer for Macro68, if anyone is interested in
  9. ;purchasing this, then please contact me.
  10. ;
  11. ;No part of this source code may be used without permission 
  12. ;in writing from Nic Wilson, but i'm easy to talk to so phone or
  13. ;email me {cbmvax|cbmehq}!cbmaus!wilson!nic@uunet.uu.net
  14. ;
  15. ;The source, docs and executable  must remain completely unmodified
  16. ;
  17. ;I would be grateful if you notify me of any bugs or suggestions
  18. ;
  19. ;If you find this source useful as an example when
  20. ;writing your own then give credit to the author
  21. ;               
  22. ;NOTE:  The macro's used in this source code, are not supplied but
  23. ;they work in a unique way.  All macros are always included but do
  24. ;not produce object code unless called.  When called for the first
  25. ;time the assembler is forced to change hunk and insert the macro.
  26. ;The macro call in the main hunk is replaced with a "JSR macro" call, 
  27. ;subsequent calls to the same macro are just replaced with the
  28. ;"JSR macro".  This has benefits, in that code is smaller because
  29. ;macros are never expanded more than once, and under a debugger
  30. ;the code looks the same as the source without falling into macro
  31. ;code that may have been written ages ago.  It can then be debugged
  32. ;without having to see old code.  If a large library of routines is
  33. ;built up this way, it also allows for bug free programming as the 
  34. ;macros will become bug free after a period of time.  All this makes
  35. ;the macros similar to function calls.  
  36. ;All this could be done with a link library, but it is done this way for 
  37. ;sheer speed.  This program assembles in under one second, with an
  38. ;average pass time of .41 seconds.  
  39. ;Try that with a C complier and blink!!
  40.  
  41.     /
  42.  
  43.                 INCPATH "includes:"
  44.                 MC68040
  45.                 strictcomments
  46.                 super                                   ;want supervisor ins
  47.                 newsyntax                               ;using new syntax
  48.                 exeobj                                  ;want executable file
  49.                 strict                                  ;all ins are strict
  50.                 objfile "Set040"                        ;ouptut name
  51.                 maclib  "commonmac/allmacs.mac"         ;pre-assembled macros
  52.                 include "commonmac/macs.i"              ;macro kludge 
  53.                 
  54.                 SECTION main,CODE                       ;needed for macros
  55.      
  56. ;**************************************
  57. ;The beginning and end of the program.
  58. ;First we do the startup stuff, parse
  59. ;the cli command string, get the output
  60. ;file handle, branch to the main code
  61. ;on return free it all up and exit 
  62. ;**************************************                
  63.                 
  64.                 pushregs                                ;save non scratch
  65.                 ParseCL                                 ;parse the command line
  66.                 FindLibs                                ;get the libraries
  67.                 CALLDOS   Output                        ;get output handle
  68.                 move.l    d0,(_stdout)                  ;save it
  69.                 bsr.b     main                          ;go do the stuff
  70.                 FreeCL                                  ;free cli args
  71.                 popregs                                 ;pop the regs
  72.                 rts                                     ;bye bye!!
  73.                 
  74. ;************************************************
  75. ;We check for V2.04, we cannot allow V36 because 
  76. ;this program calls some V37 exec calls.  Then we 
  77. ;check if we are using a 68040 CPU. 
  78. ;************************************************               
  79.                 
  80. main            movea.l   (4).w,a6                      ;get exec
  81.                 cmpi.w    #37,(LIB_VERSION,a6)          ;check if vers is 2.0x
  82.                 blt.w     check4kick                    ;if not check kickrom
  83.                 move.w    (AttnFlags,a6),d0
  84.                 btst      #AFB_68040,d0                 ;check for 68040
  85.                 bne.b     found040                      ;skip to 040 stuff
  86.                 
  87.                 
  88. ;************************************************
  89. ;If a 68030 is found then the only switch allowed
  90. ;is the -s for switch to 68040, we check for this
  91. ;and error if any other switch or none is found.
  92. ;************************************************                
  93.  
  94.                 btst      #AFB_68030,d0                 ;at least 68030 ?
  95.                 beq.w     cpuerr                        ;error if not
  96.                 tst.l     (_argv)                       ;do we have args
  97.                 beq.w     cpuerr                        ;error if not
  98.                 movea.l   (_argv),a0                    ;get the arg array
  99.                 movea.l   (a0),a0                       ;get the first arg
  100.                 cmpi.b    #'-',(a0)+                    ;is it a switch
  101.                 bne.w     cpuerr                        ;error if not
  102.                 move.b    (a0)+,d0                      ;get next byte
  103.                 bset      #5,d0
  104.                 cmpi.b    #'s',d0                       ;is it switch cpu's
  105.                 bne.w     cpuerr                        ;error if not
  106.                 bra.w     doswitch                      ;go switch 030-040
  107.                 
  108. ;********************************
  109. ;Check for CLI args, as we only 
  110. ;permit one multiple switch we do 
  111. ;not bother checking for any more
  112. ;********************************
  113.                 
  114. found040        tst.l     (_argv)                       ;check for CLI args
  115.                 beq.w      noargs                       ;skip if none
  116.                 movea.l   (_argv),a1                    ;else get ptr
  117.                 movea.l   (a1)+,a0                      ;get first arg
  118.                 move.b    (a0)+,d0                      ;get byte
  119.                 cmpi.b    #'?',d0                       ;is it usage
  120.                 beq.w     useprint                      ;go if so
  121.                 cmpi.b    #'-',d0                       ;else a switch ?
  122.                 bne.w     noargs                        ;not valid if not
  123.                 move.b    (a0)+,d0                      ;get next byte
  124.                 bset      #5,d0                         ;set lower case
  125.                 cmpi.b    #'k',d0                       ;is it kickrom
  126.                 bne.b     notkickrom                    ;skip if not
  127.                 move.l    (a1)+,(kickname)              ;else get the filename
  128.                 bra.w     instkick                      ;and do it
  129. notkickrom      cmpi.b    #'f',d0
  130.                 bne.w     notinst
  131. argloop         move.b    (a0)+,d0
  132.                 cmpi.b    #' ',d0
  133.                 ble.w     instfast
  134.                 cmpi.b    #'z',d0                       ;is it allow zcaching
  135.                 bne.b     .notz
  136.                 not.b     (zcache)
  137.                 bra.b     argloop
  138. .notz           cmpi.b    #'w',d0                       ;is mother board space
  139.                 bne.b     .notw
  140.                 not.b     (mbspace)
  141.                 bra.b     argloop
  142. .notw           cmpi.b    #'d',d0                       ;is it data cache
  143.                 bne.b     .notd
  144.                 clr.w     (dcaches)
  145.                 move.l    #datoff,(datstr)              
  146.                 bra.b     argloop
  147. .notd           cmpi.b    #'i',d0                       ;is it ins cache
  148.                 bne.b     .noti
  149.                 clr.w     (icaches)
  150.                 move.l    #insoff,(insstr)
  151.                 bra.b     argloop
  152. .noti           cmpi.b    #'t',d0
  153.                 bne.b     .nott
  154.                 not.b     (scrtit)
  155.                 bra.b     argloop                
  156. .nott           cmpi.b    #'c',d0
  157.                 bne.b     .notc
  158.                 clr.b     (z3var1+3)
  159.                 clr.b     (z3var0+3)
  160.                 bra.b     argloop                
  161. .notc           cmpi.b    #'n',d0
  162.                 bne.b     argloop
  163.                 not.b     (noclick)
  164.                 bra.w     argloop                
  165. notinst         cmpi.b    #'r',d0                       ;is it remove
  166.                 beq.w     removefr                      ;do it if so
  167.                 cmpi.b    #'s',d0
  168.                 beq.w     doswitch
  169.                 cmpi.b    #'c',d0
  170.                 bne.b     noargs
  171.                 movea.l   a0,a2
  172. maniploop       move.b    (a2)+,d0
  173.                 cmpi.b    #' ',d0
  174.                 ble.b     noargs
  175.                 cmpi.b    #'I',d0
  176.                 beq.w     icacheon
  177.                 cmpi.b    #'i',d0
  178.                 beq.w     icacheoff
  179.                 cmpi.b    #'D',d0
  180.                 beq.w     dcacheon
  181.                 cmpi.b    #'d',d0
  182.                 beq.w     dcacheoff
  183.                 cmpi.b    #'B',d0
  184.                 beq.w     bcacheon
  185.                 cmpi.b    #'b',d0
  186.                 beq.w     bcacheoff
  187.                 cmpi.b    #'A',d0
  188.                 beq.w     acacheon
  189.                 cmpi.b    #'a',d0
  190.                 beq.w     acacheoff
  191.                 cmpi.b    #'C',d0
  192.                 beq.w     con
  193.                 cmpi.b    #'c',d0
  194.                 beq.w     coff
  195.                 
  196. ;**********************************
  197. ;There were no parameters so we 
  198. ;will just display some info unless
  199. ;we find a CHIPROM setup, in which
  200. ;case we will go and change it
  201. ;to FASTROM.
  202. ;**********************************
  203.  
  204. noargs          lea       (credstr,pc),a0               ;our main credits string
  205.                 Printf                                  ;print it
  206.                 lea       (getregs,pc),a5               ;point to supervisor code
  207.                 CALLEXEC  Supervisor
  208.                 move.w    d0,(tcreg)                    ;store tcreg
  209.                 move.l    d7,(vbreg)                    ;store vbr
  210.                 move.l    d5,(it0)                      ;store itt0 in a var 
  211.                 move.l    d6,(it1)                      ;store itt1 in a var 
  212.                 move.l    d3,(dt0)                      ;store dtt0 in a var 
  213.                 move.l    d4,(dt1)                      ;store dtt1 in a var 
  214.                 move.l    d1,(table1)                   ;store urp in  var
  215.                 move.l    d1,(urpreg)                   ;user root pointer
  216.                 move.l    a0,(srpreg)                   ;supervisor root pointer
  217.                 tst.w     d0
  218.                 bpl.b     .notchiprom
  219.                 tst.l     (8,a0)
  220.                 beq.b     .notchiprom
  221.                 movea.l   (8,a0),a1
  222.                 move.l    #$80008000,(dcaches)
  223.                 move.l    (fr_kickmem,a1),d3
  224.                 cmpi.l    #'KICK',(fr_id,a1)
  225.                 beq.w     dochipkick                
  226.                 
  227. .notchiprom     moveq     #0,d3                         ;clear a reg
  228.                 move.l    d3,d4                         ;and another
  229.                 
  230.                 tst.w     d0                            ;test bit 15 of tc reg
  231.                 beq.b     tcoff                         ;clear = MMU is off
  232.                 tst.l     d1                            ;test urp
  233.                 beq.b     putzeros                      ;zero = all tables clear
  234.                 movea.l   d1,a0                         ;get into address
  235.                 move.l    (a0),d0                       ;get table 2
  236.                 clr.b     d0                            ;clear the descriptor byte
  237.                 move.l    d0,d3                         ;save it
  238.                 lea       (testcode,pc),a5              ;see if MMU set-up is ours
  239.                 CALLEXEC  Supervisor
  240.                 tst.l     d0                            ;test result
  241.                 beq.b     isours
  242.                 lea       (kickinst,pc),a0
  243.                 cmpi.l    #'FAST',(fr_id,a4)
  244.                 beq.b     ourkick
  245.                 bmi.b     notours                       ;nope not ours
  246.  
  247. tcoff           clr.l     (table1)
  248.                 bra.b     putzeros
  249. isours          lea       (fastinst,pc),a0              ;else get ours string
  250. ourkick         bsr.b     fprint                        ;print it
  251. notours         tst.l     d3                            ;test table 2 
  252.                 beq.b     putzero                       ;skip if null
  253.                 movea.l   d3,a0                         ;else get in add reg
  254.                 move.l    (a0),d0                       ;get table 3
  255.                 clr.b     d0                            ;extract address
  256.                 move.l    d0,d4                         ;replace d4
  257.  
  258. putzeros        move.l    d3,(table2)                   ;fill table 2 var
  259. putzero         move.l    d4,(table3)                   ;and table 3 var
  260.                 tst.l     d2                            ;test data cache
  261.                 bpl.b     printoff                      ;branch if off
  262.                 lea       (daton,pc),a0                 ;else get on string
  263.                 bsr.b     fprint                        ;print it
  264.                 bra.b     skipoff                       ;skip off code
  265. printoff        lea       (datoff,pc),a0                ;get off code
  266.                 bsr.b     fprint                        ;print it
  267. skipoff         tst.w     d2                            ;test ins cache
  268.                 bpl.b     printoff1                     ;branch if off
  269.                 lea       (inson,pc),a0                 ;else get on string
  270.                 bsr.b     fprint                        ;print it
  271.                 bra.b     skipoff1                      ;skip off code
  272. printoff1       lea       (insoff,pc),a0                ;get off string
  273.                 bsr.b     fprint                        ;print it
  274. skipoff1        lea       (infostr,pc),a0               ;get rest of info
  275.                 lea       (table1,pc),a1                ;data for string
  276.                 bsr.b     fprint                        ;print it
  277.                 lea       (usage1,pc),a0                ;info on usage
  278.                 bsr.b     fprint                        ;print it
  279.                 rts                                     ;we're outa here!!
  280.         
  281. fprint        Printf
  282.         rts
  283.         
  284. ;***********************************************
  285. ;The cache manipulation area, all cache modes
  286. ;are handled here also copyback and writethrough
  287. ;for the data cache.
  288. ;bits to change in D0 and the Mask in D1
  289. ;***********************************************        
  290.         
  291. icacheon        moveq     #0,d0
  292.                 or.l      #CACRF_EnableI,d0
  293.                 move.l    d0,d1
  294.                 bra.b     docache
  295.                 
  296. icacheoff       moveq     #0,d0
  297.                 move.l    d0,d1
  298.                 or.l      #CACRF_EnableI,d1
  299.                 bra.b     docache
  300.  
  301. dcacheon        moveq     #0,d0
  302.                 or.l      #CACRF_EnableD,d0
  303.                 move.l    d0,d1
  304.                 bra.b     docache
  305.  
  306. dcacheoff       moveq     #0,d0
  307.                 move.l    d0,d1
  308.                 or.l      #CACRF_EnableD,d1
  309.                 bra.b     docache
  310.  
  311. acacheon        moveq     #0,d0
  312.                 or.l      #CACRF_EnableI|CACRF_EnableD,d0
  313.                 move.l    d0,d1
  314.                 CALLEXEC  CacheControl
  315.                 bra.b     con
  316.  
  317. acacheoff       moveq     #0,d0
  318.                 move.l    d0,d1
  319.                 or.l      #CACRF_EnableI|CACRF_EnableD,d1
  320.                 CALLEXEC  CacheControl
  321.                 bra.b     coff
  322.                 
  323. bcacheon        moveq     #0,d0
  324.                 or.l      #CACRF_EnableI|CACRF_EnableD,d0
  325.                 move.l    d0,d1
  326.                 bra.b     docache
  327.  
  328. bcacheoff       moveq     #0,d0
  329.                 move.l    d0,d1
  330.                 or.l      #CACRF_EnableI|CACRF_EnableD,d1
  331.  
  332. docache         CALLEXEC  CacheControl
  333. dout            bra.w     maniploop
  334.                      
  335. con             lea       (getmttx,pc),a5
  336.                 CALLEXEC  Supervisor
  337.                 bset      #5,d1
  338.                 cmp.l     (z3var1,pc),d1
  339.                 bne.w     testerr
  340.                 bset      #5,d0
  341.                 cmp.l     (z3var0,pc),d0
  342.                 bne.w     testerr
  343.                 bra.b     cout
  344.                 
  345. coff            lea       (getmttx,pc),a5
  346.                 CALLEXEC  Supervisor
  347.                 bclr      #5,d1
  348.                 cmpi.l    #$4fbc000,d1
  349.                 bne.w     testerr
  350.                 bclr      #5,d0
  351.                 cmpi.l    #$8f7c000,d0
  352.                 bne.w     testerr
  353. cout            lea       (setdttx,pc),a5
  354.                 CALLEXEC  Supervisor
  355.                 bra.b     dout
  356.                 
  357. ;************************************************************
  358. ;This function is the start of the kickrom code, it allocates
  359. ;all memory required in one big block in chip ram in the 
  360. ;highest aligned block possible.  The MMU set up remaps the 
  361. ;area to $F00000 so that the new kickstart will not see this 
  362. ;chip ram, making our set-up safe through the boot process.
  363. ;
  364. ;We allocate the required ram as high as possible by alloc-
  365. ;ating all of the largest block available, calculating the
  366. ;end address of this new block, subtracting the required 
  367. ;amount and then lowering this new address to the closest
  368. ;boundary required.  Once we have this new address we give
  369. ;back the allocated block and AllocAbs the new location.
  370. ;This is the reason for the Forbid, we cannot allow some
  371. ;other task to jump in ahead of us and take some ram in
  372. ;between our alloc, de-alloc and allocabs.
  373. ;************************************************************                           
  374.                            
  375. instkick        lea       (testcode,pc),a5              ;get registers
  376.                 CALLEXEC  Supervisor                    ;fetch it
  377.                 tst.l     d0
  378.                 bmi.w     mmuerr
  379.                 not.b     (kickflag)                    ;set the flag
  380.                 JSREXEC   Forbid                        ;multitasking off
  381.                 move.l    #MEMF_CHIP+MEMF_LARGEST,d1     
  382.                 JSREXEC   AvailMem                      ;get largest chip
  383.                 cmp.l     #559592+fr_SIZEOF,d0          ;enough?
  384.                 blt.w     mem1err                       ;err if not
  385.                 move.l    d0,d2                         ;save a copy
  386.                 move.l    #MEMF_CHIP,d1                 ;want chip
  387.                 JSREXEC   AllocMem                      ;allocate it
  388.                 tst.l     d0                            ;did we?
  389.                 beq.w     mem1err                       ;err if not
  390.                 move.l    d0,-(sp)                      ;save it
  391.                 add.l     d2,d0                         ;add largest
  392.                 subi.l    #559592+fr_SIZEOF,d0          ;sub amount required
  393.                 andi.l    #$ffff8000,d0                 ;alignment required
  394.                 move.l    d2,d1                         ;allocated size
  395.                 move.l    d0,d2                         ;new location
  396.                 movea.l   (sp)+,a1                      ;get allocated area
  397.                 move.l    d1,d0                         ;shift size for call
  398.                 JSREXEC   FreeMem                       ;free the block
  399.                 movea.l   d2,a1                         ;get new location
  400.                 move.l    #559592+fr_SIZEOF,d0          ;size needed
  401.                 JSREXEC   AllocAbs                      ;allocate it
  402.                 move.l    d0,(kickmem)                  ;save ptr
  403.                 JSREXEC   Permit                        ;multitasking on
  404.                 move.l    (kickmem,pc),d0               ;get ptr
  405.                 beq.w     mem1err                       ;exit if error
  406.                 
  407. ;********************
  408. ;Clear this new block
  409. ;********************
  410.                 
  411.                 movea.l   d0,a0
  412.                 addi.l    #559592+fr_SIZEOF,d0          ;get the end address
  413. ..loop          clr.w     (a0)+                         ;clear the whole block
  414.                 cmpa.l    d0,a0                         ;with words, may not be
  415.                 blt.b     ..loop                        ;multiples of longs
  416.                 
  417. ;************************************
  418. ;Set up pointers to each table within 
  419. ;this new block for the kickstart and
  420. ;ATC entries.
  421. ;************************************
  422.                 
  423.                 move.l    (kickmem,pc),d0               ;get block start
  424.                 addi.l    #524288,d0                    ;add kickstart size
  425.                 move.l    d0,(table1)                   ;table 1
  426.                 move.l    #512,d1
  427.                 add.l     d1,d0                       
  428.                 move.l    d0,(table2)                   ;table 2
  429.                 add.l     d1,d0                        
  430.                 move.l    d0,(table3)                   ;table 3
  431.                 addi.l    #16384,d0
  432.                 move.l    d0,(table22)                  ;2nd table 2
  433.                 add.l     d1,d0
  434.                 move.l    d0,(table23)                  ;2nd table 3
  435.                 addi.l    #16384,d0                     ;get end of table2/3
  436.                 movea.l   d0,a0                         ;our struct
  437.                 lea       (fr_SIZEOF,a0),a0
  438.                 move.l    a0,(kickchip)
  439.                 lea       (crunmmu,pc),a1               ;get the chip code
  440.                 lea       (crunend,pc),a2               ;and its end 
  441. ..kmloop        move.w    (a1)+,(a0)+                   ;move it to chip
  442.                 cmpa.l    a2,a1                         ;until finished
  443.                 bne.b     ..kmloop
  444.                 bra.w     gotkick                                 
  445.                                   
  446. ;**************************
  447. ;OK so we have to install
  448. ;FASTROM, but first we make
  449. ;sure that the MMU isn't 
  450. ;already in use
  451. ;**************************                
  452.  
  453. instfast        lea       (getregs,pc),a5               ;get registers
  454.                 CALLEXEC  Supervisor                    ;fetch it
  455.                 tst.w     d0                            ;is it enabled
  456.                 bpl.b     mmuok                         ;no its disabled
  457.                 tst.l     d1                            ;test urp reg
  458.                 beq.b     .mmuerr                       ;exit (saves a reloc)
  459.                 lsr.l     #1,d1                         ;make sure its even
  460.                 add.l     d1,d1                         ;quicker than lsl.l
  461.                 movea.l   d1,a0
  462.                 movea.l   (8,a0),a0                     ;get third ptr
  463.                 cmpi.l    #'NICS',(fr_id,a0)            ;is it our fastrom
  464.                 beq.w     ourfastrom
  465. .mmuerr         bra.w     mmuerr
  466.                 
  467.                 
  468. ;************************************
  469. ;Now we allocate 512k of memory 
  470. ;aligned on a 8k boundary this is
  471. ;handled by my AllocAligned macro and
  472. ;it will clear the block if the 
  473. ;MEMF_CLEAR attribute is set. It will
  474. ;return an aligned block according to
  475. ;the value in D2
  476. ;************************************
  477.                 
  478. mmuok           move.l    #524288,d0                    ;512k size
  479.                 move.l    #MEMF_FAST,d1                 ;clear not required
  480.                 move.l    #32768,d2                     ;32k boundary
  481.                 AllocAligned                            
  482.                 tst.l     d0                            ;did we get it
  483.                 beq.w     mem1err                       ;exit if not
  484.                 move.l    d0,(kickmem)                  ;save the ptr
  485.                 
  486. ;***********************
  487. ;Now we allocate memory 
  488. ;for the first table
  489. ;***********************
  490.                 
  491.                 move.l    #512,d3                       ;we'll use this more
  492.                 move.l    d3,d0                         ;size of table1
  493.                 move.l    #MEMF_FAST+MEMF_CLEAR,d1      ;we want fast & clear
  494.                 move.l    d3,d2                         ;512 byte boundary
  495.                 AllocAligned                            ;get it
  496.                 tst.l     d0                            ;did we?
  497.                 beq.w     mem2err                       ;exit if not
  498.                 move.l    d0,(table1)                   ;save it
  499.                 
  500. ;**********************
  501. ;Now we allocate memory 
  502. ;for the second table
  503. ;**********************
  504.                 
  505.                 move.l    d3,d0                         ;size of table2
  506.                 move.l    #MEMF_FAST+MEMF_CLEAR,d1      ;we want fast & clear
  507.                 move.l    d3,d2                         ;512 byte boundary
  508.                 AllocAligned                            ;get it
  509.                 tst.l     d0                            ;did we?
  510.                 beq.w     mem3err                       ;exit if not
  511.                 move.l    d0,(table2)                   ;save it
  512.  
  513. ;**********************
  514. ;Now we allocate memory
  515. ;for the third table
  516. ;**********************
  517.                 
  518.                 move.l    #16384,d0                     ;size of table3
  519.                 move.l    #MEMF_FAST+MEMF_CLEAR,d1      ;fast and clear
  520.                 move.l    d3,d2                         ;512 byte boundary
  521.                 AllocAligned                            ;get it
  522.                 tst.l     d0                            ;did we?
  523.                 beq.w     mem4err                       ;exit if not
  524.                 move.l    d0,(table3)                   ;save it
  525.                 
  526. ;**************************
  527. ;Now we allocate memory for
  528. ;the second-second table
  529. ;**************************
  530.                 
  531.                 move.l    d3,d0                         ;size of table2-2
  532.                 move.l    #MEMF_FAST+MEMF_CLEAR,d1      ;we want fast & clear
  533.                 move.l    d3,d2                         ;512 byte boundary
  534.                 AllocAligned                            ;get it
  535.                 tst.l     d0                            ;did we?
  536.                 beq.w     mem5err                       ;exit if not
  537.                 move.l    d0,(table22)                  ;save it
  538.  
  539. ;**************************
  540. ;Now we allocate memory for
  541. ;the second-third table
  542. ;**************************
  543.                 
  544.                 move.l    #16384,d0                     ;size of table3
  545.                 move.l    #MEMF_FAST+MEMF_CLEAR,d1      ;fast and clear
  546.                 move.l    d3,d2                         ;512 byte boundary
  547.                 AllocAligned                            ;get it
  548.                 tst.l     d0                            ;did we?
  549.                 beq.w     mem6err                       ;exit if not
  550.                 move.l    d0,(table23)                  ;save it
  551.                 
  552. ;****************************************
  553. ;Now we allocate a structure to hold 
  554. ;all the old values so we can remove all
  555. ;this if asked to this will be linked on
  556. ;to an invalid entry in table 1 so we 
  557. ;can retreive it later if needed
  558. ;***************************************                
  559.                 
  560.                 move.l    #fr_SIZEOF,d0                 ;size of struct
  561.                 move.l    #MEMF_FAST,d1                 ;fast
  562.                 move.l    #32768,d2                     ;32k byte boundary
  563.                 AllocAligned                            ;get it
  564.                 tst.l     d0                            ;did we?
  565.                 beq.w     mem7err                       ;exit if not
  566. gotkick         movea.l   d0,a4
  567.                 move.l    d0,(fr_struct,a4)             ;save it
  568.                 move.l    (table23,pc),(fr_table5,a4)
  569.                 move.l    (table22,pc),(fr_table4,a4)
  570.                 move.l    (table3,pc),(fr_table3,a4)
  571.                 move.l    (table2,pc),(fr_table2,a4)
  572.                 move.l    (table1,pc),(fr_table1,a4)
  573.                 move.l    (kickmem,pc),(fr_kickmem,a4)
  574.                 move.l    #'NICS',(fr_id,a4)            ;our id
  575.                 
  576. ;******************************************************************
  577. ;If we're kickromming we check the supplied filename, if a floppy
  578. ;drive only we read the disk to see if its a valid kickstart disk,
  579. ;if no disk is found we bring up a requester and ask for one,
  580. ;else we check to see if its an old kickstart or superkickstart.
  581. ;If superkickstart we bring up a requester asking if they want 
  582. ;kick 1.3 or v2.0.  If the filename is a pointer to a file we
  583. ;load that file check if its a 256k kick or 512k kick and set it up
  584. ;******************************************************************                
  585.                 
  586.                 tst.b     (kickflag,pc)                 ;check the flag
  587.                 bpl.w     notkick                       ;skip if not kickrom
  588.                 
  589.                 move.l    #'KICK',(fr_id,a4)            ;change the id
  590.                 movea.l   (kickname,pc),a0              ;get the filename
  591.                 move.b    (a0)+,d0                      ;get first byte
  592.                 bset      #5,d0                         ;set for lower case
  593.                 cmpi.b    #'d',d0                       ;is it a d
  594.                 bne.w     notrack                       ;not trackdisk if not
  595.                 move.b    (a0)+,d0                      ;get next byte
  596.                 bset      #5,d0                         ;lower case
  597.                 cmpi.b    #'f',d0                       ;is it an f
  598.                 bne.w     notrack                       ;not trackdisk if not
  599.                 move.b    (a0)+,d0                      ;get next byte
  600.                 cmpi.b    #$30,d0                       ;is it in range
  601.                 blt.w     notrack                       ;skip if not
  602.                 cmpi.b    #$33,d0                       ;check upper range
  603.                 bgt.w     notrack                       ;skip if not
  604.                 move.b    (a0),d0                       ;get next byte
  605.                 cmpi.b    #':',d0                       ;is it a colon
  606.                 bne.w     notrack                       ;skip if not
  607.                 movea.l   (kickname,pc),a0              ;get the name
  608.                 tst.b     (4,a0)                        ;is it null terminated
  609.                 bne.w     notrack                       ;skip out if not
  610.                 InitDrive                               ;initialise the drive
  611.                 tst.l     d0                            ;test result
  612.                 ble.w     kickerr                       ;end if error
  613.                 move.l    d1,(ioreq)                    ;save the iorequest
  614. .testdisk       movea.l   (ioreq,pc),a1
  615.                 DiskIn
  616.                 tst.l     d0
  617.                 beq.b     .diskisin
  618.                 lea       (easyreq,pc),a0               ;else get easy struct
  619.                 move.l    #diskgads,(es_GadgetFormat,a0) ;change the gadgets
  620.                 move.l    #disktext,(es_TextFormat,a0)  ;and the the text
  621.                 move.l    #DISKINSERTED,(esidcmp)
  622.                 move.l    #kickname,d0                  ;data
  623.                 bsr.w     requester                     ;do the requester
  624.                 tst.l     d0                            ;check their answer
  625.                 beq.w     kickabort                     ;they want kick 2.0
  626.                 bra.b     .testdisk
  627. .diskisin       movea.l   (kickmem,pc),a0               ;get the buffer
  628.                 movea.l   (ioreq,pc),a1                 ;and the ioreq
  629.                 moveq     #0,d0                         ;offset 'bootblock'
  630.                 move.l    #TD_SECTOR*2,d1               ;two sectors
  631.                 ReadBlocks                              ;read it
  632.                 bsr.w     motoroff                
  633.                 tst.l     d0                            ;check result
  634.                 bne.w     kick1err                      ;end if error
  635.                 movea.l   (kickmem,pc),a0               ;get buffer
  636.                 cmpi.l    #'KICK',(a0)                  ;check if kickstart
  637.                 bne.w     kick1err                      ;end if not
  638.                 cmpi.l    #'SUP0',(4,a0)                ;check super
  639.                 bne.b     notsuper                      ;skip if not
  640.                 lea       (easyreq,pc),a0               ;else get easy struct
  641.                 move.l    #eskickgads,(es_GadgetFormat,a0) ;change the gadgets
  642.                 move.l    #eskick,(es_TextFormat,a0)    ;and the the text
  643.                 moveq     #0,d0                         ;no data
  644.                 move.l    d0,(esidcmp)                  ;clear idcmp
  645.                 bsr.w     requester                     ;do the requester
  646.                 tst.l     d0                            ;check their answer
  647.                 beq.b     kick2.0                       ;they want kick 2.0
  648.                 move.l    #$400,d0                      ;offset for 1.3 super
  649.                 bra.b     loadkick                      ;and go load it
  650. kick2.0         move.l    #$40400,d0                    ;offset for 2.0 super
  651.                 move.l    #$80000,d1                    ;512k length
  652.                 movea.l   (kickmem,pc),a0               ;get buffer
  653.                 bra.b     load2.0                       ;and go load it
  654. notsuper        move.l    #$200,d0                      ;offset for 1.3 normal
  655. loadkick        movea.l   (kickmem,pc),a0               ;get buffer
  656.                 lea       ($40000,a0),a0                ;add 256k for 1.3
  657.                 move.l    #$40000,d1                    ;and 256k as length
  658. load2.0         movea.l   (ioreq,pc),a1                 ;get it requester
  659.                 ReadBlocks                              ;read the data
  660.                 bsr.b     motoroff
  661.                 tst.l     d0                            ;test result
  662.                 bne.w     kick1err                      ;end if error
  663.                 movea.l   (ioreq,pc),a1                 ;get ioreq
  664.                 ExitDrive                               ;un-init the drive
  665.                 bra.b     endtrack                      ;and skip file part
  666.                 
  667. motoroff        move.l    d0,-(sp)
  668.                 movea.l   (ioreq,pc),a1
  669.                 MotorOff
  670.                 move.l    (sp)+,d0
  671.                 rts
  672.                 
  673. notrack         movea.l   (kickname,pc),a1              ;get the name
  674.                 movea.l   (kickmem,pc),a0               ;and the buffer
  675.                 moveq     #4,d0                         ;want 4 bytes
  676.                 ReadFile                                ;read it
  677.                 movea.l   (kickname,pc),a1              ;get the name
  678.                 movea.l   (kickmem,pc),a0               ;and the buffer
  679.                 cmpi.w    #$1111,(a0)                   ;what type of kick
  680.                 beq.s     dosmall                       ;is a 256k kick
  681.                 cmpi.w    #$1114,(a0)                   ;else is it 512k
  682.                 bne.w     kickfilerr                    ;end if not kickstart
  683.                 move.l    #524288,d0                    ;else set size
  684.                 bra.b     dobig                         ;and go get it
  685.                 
  686. dosmall         clr.l     (a0)                          ;clear the kick id
  687.                 lea       ($40000,a0),a0                ;add 256k to 1.3 buffer
  688.                 move.l    #262144,d0                    ;and its size
  689. dobig           ReadFile                                ;read the data
  690. endtrack        movea.l   (kickmem,pc),a0
  691.                 cmpi.w    #$1114,(a0)+                  ;is it 2.0
  692.                 bne.w     not2.0                        ;skip if not
  693.                 lea       (patch,pc),a0                 ;else tell we're patching
  694.                 Printf
  695.                 movea.l   (kickmem,pc),a1               ;get buffer
  696.                 lea       ($7ffff,a1),a1                ;get end address
  697.                 
  698. ;**************************************************
  699. ;This next part scans through a V2.0x kickstart and
  700. ;patches out any 68040 MMU instructions that would
  701. ;corrupt our set up.  Each one found is converted
  702. ;into a 'nop' instruction.
  703. ;**************************************************
  704.                 
  705.                 
  706.                 movea.l   (kickmem,pc),a0               ;get buffer
  707. .loop           cmpa.l    a1,a0                         ;are we finsihed
  708.                 bgt.w     not2.0                        ;exit if so
  709.                 cmpi.w    #$4e7b,(a0)+                  ;look for movec 
  710.                 bne.b     .loop                         ;loop to find
  711.                 
  712.                 move.b    (1,a0),d0                     ;if next byte less than
  713.                 cmpi.b    #3,d0                         ;3 we're not interested
  714.                 blt.b     .loop                         ;so loop back
  715.                 cmpi.b    #7,d0                         ;if it is greater than
  716.                 bgt.b     .loop                         ;7 we're not interested
  717.                 moveq     #$f,d0  
  718.                 and.b     (a0),d0                       ;test bits 0-3 if >0 
  719.                 bne.b     .loop                         ;we're not interested
  720.                 move.w    #$4e71,(-2,a0)                ;OK so we've got an MMU
  721.                 move.w    #$4e71,(a0)+                  ;instruction so nop'em
  722.                 bra.b     .loop                         ;and loop
  723.                 
  724. ;*******************************************
  725. ;Once all the above mods are made we correct
  726. ;the checksum of the kickstart
  727. ;*******************************************
  728.  
  729. not2.0          movea.l   (kickmem,pc),a0
  730.                 movea.l   a0,a1
  731.                 lea       ($7ffe8,a0),a0
  732.                 moveq     #0,d5
  733.                 move.l    d5,(a0)                       ;clear checksum 
  734.                 moveq     #-1,d1
  735.                 moveq     #1,d2
  736. .oneloop        add.l     (a1)+,d5
  737.                 bcc.b     .csloop               
  738.                 addq.l    #1,d5
  739. .csloop         dbf       d1,.oneloop           
  740.                 dbf       d2,.oneloop
  741.                 moveq     #-1,d0
  742.                 sub.l     d5,d1
  743.                 move.l    d1,(a0)
  744.                 CALLEXEC  CacheClearU                   ;flush the changes 
  745.                 bra.w     skipclick
  746.                 
  747. ;**************************************************
  748. ;Now we copy the ROM image,  that's the beauty of
  749. ;assembler, we can take advantage of the efficiency
  750. ;of the MOVE16 instruction. C programmers have no 
  751. ;idea, they call CopyMemQuick and hope for the
  752. ;best!!  Plus it saves us from having to flush
  753. ;the cache as MOVE16 instruction prevents the
  754. ;data from being cached and invalidates any entry
  755. ;in the cache.
  756. ;**************************************************                
  757.                 
  758. notkick         move.l    #$7fff,d0                     ;(512k/16)-1 loop count
  759.                 lea       ($f80000),a0                  ;ROM kickstart address
  760.                 movea.l   (kickmem,pc),a1               ;destination
  761. ..turbocopy     move16    (a0)+,(a1)+                   ;16 bytes at a time
  762.                 dbf       d0,..turbocopy                ;loop till done
  763.                                 
  764. ;***************************************
  765. ;This will change the Workbench screen
  766. ;title to Amiga FastBench if the command
  767. ;line option allows it.
  768. ;***************************************                
  769.                 
  770. lookbyte        tst.b     (scrtit,pc)
  771.                 bmi.b     skiptit
  772.                 subq.l    #1,a1
  773.                 cmpi.b    #'W',-(a1)
  774.                 bne.b     lookbyte
  775.                 cmpi.b    #'o',(1,a1)
  776.                 bne.b     lookbyte
  777.                 cmpi.b    #'r',(2,a1)
  778.                 bne.b     lookbyte
  779.                 cmpi.b    #'k',(3,a1)
  780.                 bne.b     lookbyte
  781.                 cmpi.b    #' ',(-1,a1)
  782.                 bne.b     lookbyte
  783.                 cmpi.b    #'a',(-2,a1)
  784.                 bne.b     lookbyte
  785.                 move.b    #'F',(a1)+
  786.                 move.b    #'a',(a1)+
  787.                 move.b    #'s',(a1)+
  788.                 move.b    #'t',(a1)+
  789.                 
  790. ;***********************************************
  791. ;This will patch the kickstart to stop drives
  792. ;from clicking if the command line option allows
  793. ;it
  794. ;***********************************************                
  795.                 
  796. skiptit         tst.b     (noclick,pc)
  797.                 beq.b     skipclick
  798.                 movea.l   (4).w,a0
  799.                 lea       (DeviceList,a0),a0
  800.                 lea       (tdname,pc),a1
  801.                 CALLEXEC  FindName
  802.                 tst.l     d0
  803.                 beq.b     skipclick
  804.                 movea.l   d0,a0
  805.                 movea.l   (LN_NAME,a0),a0
  806. .look6b         cmpi.b    #$6b,(a0)+                    ;find bchg instruction
  807.                 bne.b     .look6b
  808.                 tst.b     (a0)+                         ;2nd byte of instruction
  809.                 bne.b     .look6b
  810.                 cmpi.b    #1,(a0)+                      ;is it the one we want
  811.                 bne.b     .look6b                       ;nope! keep looking
  812.                 suba.l    #$f80003,a0                   ;calculate offset value
  813.                 adda.l    (kickmem,pc),a0               ;add new start address
  814.                 move.b    #$eb,(a0)                     ;change it to bset
  815.                 
  816.  
  817. ;**************************************************
  818. ;place the pointer to the second table in the first
  819. ;and 'OR' in the descriptor type the rest are set
  820. ;as invalid but we link our structure of old values
  821. ;onto an invalid descriptor.
  822. ;**************************************************                
  823.                 
  824. skipclick       movea.l   (table1,pc),a0                ;get first table
  825.                 move.l    (table2,pc),d0                ;get second table
  826.                 or.b      #3,d0                         ;UDT descriptor
  827.                 move.l    d0,(a0)+                      ;shove it in
  828.                 move.l    (table22,pc),d0               ;get 2nd table 2
  829.                 or.b      #3,d0                         ;UDT descriptor
  830.                 move.l    d0,(a0)+                      ;shove it in
  831.                 move.l    a4,(a0)                       ;link our struct on
  832.                                                         ;invalid entry UDT=0
  833. ;****************************************************                
  834. ;Now we set-up table 2, 128 pointers to table3 entries
  835. ;and descriptor type 'ORed' in.
  836. ;****************************************************
  837.                 
  838.                 movea.l   (table2,pc),a0                ;get table 2
  839.                 move.l    (table3,pc),d2                ;get table 3
  840.                 moveq     #127,d0                       ;128 entries
  841.                 or.l      #3,d2                         ;UDT descriptor 
  842. dotable2        move.l    d2,(a0)+                      ;move one in
  843.                 addi.l    #128,d2                       ;add next address
  844.                 dbf       d0,dotable2                   ;loop till done
  845.                 
  846. ;******************************************                
  847. ;Addresses from $0 up to $f7ffff marked as 
  848. ;global, non-cachable serialized
  849. ;******************************************                
  850.                               
  851.                 movea.l   (table3,pc),a0
  852.                 move.l    #$441,d1
  853.                 move.l    #1983,d0
  854. dotable32       move.l    d1,(a0)+
  855.                 addi.l    #$2000,d1
  856.                 dbf       d0,dotable32
  857.                 
  858. ;**********************************************
  859. ;If kickrom, this will map the Chip memory area 
  860. ;we allocated as $F00000 - $FFFFFF to fool the 
  861. ;kickstart as to the size of chip memory
  862. ;**********************************************
  863.                 
  864.                 tst.b     (kickflag,pc)
  865.                 beq.b     skipk               
  866.                 movea.l   (table3,pc),a1
  867.                 move.l    (kickmem,pc),d0
  868.                 moveq     #11,d1
  869.                 lsr.l     d1,d0
  870.                 lea       (a1,d0.l),a1
  871.                 move.l    #$f00000,d1
  872.                 sub.l     (kickmem,pc),d1
  873.                 moveq     #63,d0
  874. dokickm         add.l     d1,(a1)+
  875.                 dbf       d0,dokickm            
  876.                 
  877. ;**********************************************
  878. ;If allowed by the CLI switch this will map the
  879. ;ZorroII memory area $200000 - $A00000 as
  880. ;cachable copyback
  881. ;**********************************************
  882.                 
  883. skipk           tst.b     (zcache,pc)
  884.                 beq.b     skipz                
  885.                 movea.l   (table3,pc),a1
  886.                 lea       ($400,a1),a1
  887.                 move.l    #1023,d0
  888.                 move.b    #$21,d1
  889. dozorro         move.b    d1,(3,a1)
  890.                 dbf       d0,dozorro            
  891.                 
  892. ;*************************************************
  893. ;the rest of table 3 for the kickstart remap
  894. ;64 entries mapping 8k each, and write protected
  895. ;************************************************* 
  896.                
  897. skipz           moveq     #63,d0
  898.                 move.l    (kickmem,pc),d1
  899.                 or.l      #$405,d1
  900. dotable33       move.l    d1,(a0)+
  901.                 addi.l    #$2000,d1
  902.                 dbf       d0,dotable33
  903.                 
  904. ;*********************************************
  905. ;The second 16MB/256k segments are mapped here
  906. ;each entry maps 8k of the 256k making a total
  907. ;of 32 per 256k & 64 of these map the 16MB
  908. ;These are set for Data Cachable Copyback as 
  909. ;memory on some boards will reside here but an
  910. ;optional cli flag allows this to be changed
  911. ;to writethrough
  912. ;*********************************************
  913.                 
  914.                 move.l    #2047,d0
  915.                 move.l    #$1000421,d1
  916.                 tst.b     (mbspace,pc)
  917.                 beq.b     dotable34
  918.                 bclr      #5,d1
  919. dotable34       move.l    d1,(a0)+
  920.                 addi.l    #$2000,d1
  921.                 dbf       d0,dotable34          
  922.                 
  923. ;******************************************************                
  924. ;Now we set-up table 2 for the second 32 Meg address
  925. ;space, 128 pointers to table3 entries and descriptor 
  926. ;type 'ORed' in.  Each table3 entry controls 8k of
  927. ;the 256k of each table 2 entry, each is a long word
  928. ;so the address increment value is 32*4 = 128 as shown. 
  929. ;******************************************************
  930.                 
  931.                 movea.l   (table22,pc),a0
  932.                 move.l    (table23,pc),d2
  933.                 moveq     #127,d0
  934.                 or.l      #3,d2
  935. dotable22       move.l    d2,(a0)+
  936.                 addi.l    #128,d2
  937.                 dbf       d0,dotable22
  938.                 
  939. ;**************************************************************                
  940. ;and now table 3 number 2.  This maps each of the 256k segments
  941. ;in table 2 above with 32 8k page descriptors.
  942. ;**************************************************************
  943.                 
  944.                 movea.l   (table23,pc),a0
  945.                 move.l    #$2000421,d1
  946.                 move.l    #4095,d0
  947.                 tst.b     (mbspace,pc)
  948.                 beq.b     dotable23
  949.                 bclr      #5,d1
  950. dotable23       move.l    d1,(a0)+
  951.                 addi.l    #$2000,d1
  952.                 dbf       d0,dotable23
  953.                 
  954. ;***********************************
  955. ;We save the old transparent values
  956. ;straight into our structure that is
  957. ;tagged on to an invalid entry.
  958. ;A4 points to the table.
  959. ;***********************************                
  960.  
  961.                 lea       (getmttx,pc),a5
  962.                 CALLEXEC  Supervisor
  963.                 move.l    d0,(fr_dtt0,a4)
  964.                 move.l    d1,(fr_dtt1,a4)
  965.                 move.l    d2,(fr_itt0,a4)
  966.                 move.l    d3,(fr_itt1,a4)
  967.                 
  968. ;***********************************************************
  969. ;ZorroIII Memory expansion space is set for Data Cachable
  970. ;Copyback and the ZorroIII Expansion space is invalid at
  971. ;the moment. 
  972. ;This is all done in the Transparent Translation
  973. ;instruction and data registers.
  974. ;When setting all this up we do as much as we can without
  975. ;being disabled.  We can only disable for a very short
  976. ;period of time, so there is no need to be disabled for 
  977. ;the entire installation.  The Transparent settings will
  978. ;take effect immediately but thats ok too!  We only need
  979. ;be disabled for turning the MMU on. 
  980. ;
  981. ;
  982. ;OK, now the magic stuff.  Stick in the keys, clean out the
  983. ;carby, give a couple of pumps, and a bit of choke and lets 
  984. ;see if she'll start.
  985. ;***********************************************************                
  986.                 
  987.                 move.l    (table1,pc),d3        ;get table start
  988.                 move.l    (z3var0,pc),d6        ;copyback up to  $0FFFFFFF
  989.                 move.l    (z3var1,pc),d4        ;copyback up to  $07FFFFFF
  990.                 move.w    #$c000,(tcreg)
  991.                 move.l    (table1,pc),(urpreg)
  992.                 move.l    (table1,pc),(srpreg)
  993.                 move.l    d4,(dt1)              ;save for printing
  994.                 move.l    d6,(dt0)              ;save for printing
  995.                 move.l    #$c040,d5
  996.                 tst.b     (kickflag,pc)
  997.                 bmi.b     .leaveon
  998.                 moveq     #0,d0                 ;d0 = cache bits
  999.                 move.l    d0,d1                 ;clear d1
  1000.                 or.l      #CACRF_EnableI|CACRF_EnableD,d1 ;ins & data caches mask
  1001.                 CALLEXEC  CacheControl          ;turn 'em both off
  1002.                 bsr.w     flushcaches           ;flush the caches
  1003. .leaveon        moveq     #0,d2                 ;need a clear reg
  1004.                 lea       (setmmu,pc),a5        ;set-up some of the regs
  1005.                 JSREXEC   Supervisor
  1006.                 move.l    d0,(vbreg)
  1007.                 JSREXEC   Disable               ;really selfish!!
  1008.                 lea       (magic,pc),a5         ;turn this all on
  1009.                 JSREXEC   Supervisor            
  1010.                 JSREXEC   Enable                
  1011.                 move.l    d4,(it1)              ;save for printing
  1012.                 move.l    d5,(it0)              ;save for printing
  1013.                 lea       (fastinst,pc),a0      ;finsihed string
  1014.                 bra.w     printit               ;we're outa here
  1015.                                                 
  1016.                 
  1017. setmmu          movec     d2,tc                 ;make sure the MMU is off
  1018.                 nop
  1019.                 pflusha                         ;invalidate all ATC entries
  1020.                 nop
  1021.                 movec     d3,urp                ;set the user root pointer
  1022.                 movec     d3,srp                ;and the supervisor one
  1023.                 movec     d4,dtt1               ;set the data trans' reg
  1024.                 movec     d5,dtt0               ;control the lowest 16MB
  1025.                 move.l    #$8f7c000,d5             
  1026.                 move.l    #$4fbc000,d4          
  1027.                 movec     d4,itt1               ;and set the itt1 reg
  1028.                 movec     d5,itt0               ;and the itt0 reg
  1029.                 movec     vbr,d0
  1030.                 rte
  1031.  
  1032. magic           tst.b     (kickflag,pc)
  1033.                 bmi.b     notfast
  1034.                 move.w    #$c000,d2             ;set for MMU on with 8k pages
  1035.                 movec     d2,tc                 ;IGNITION...
  1036.                 movec     d6,dtt0               ;set dtt0 for ZorroIII control
  1037.                 move.l    (dcaches,pc),d0       ;requested cache settings
  1038.                 movec     d0,cacr               ;and do it
  1039.                 rte                             ;I can smell the rubber..
  1040. notfast         move.l    #$80008000,d0
  1041.                 movec     d0,cacr
  1042.                 lea       (crunjmp,pc),a0
  1043.                 moveq     #0,d3
  1044.                 lea       (crun,pc),a6
  1045. crunloop        jmp       (a6)
  1046. crunit          reset
  1047.                 reset
  1048. crun            move.w    ($dff010),d0            ;read something 
  1049.                 subq.l    #1,d3
  1050.                 bpl.b     crun
  1051.                 move.b    #3,($bfe201)
  1052.                 move.b    #2,($bfe001)
  1053.                 cmpa.l    a0,a6
  1054.                 beq.b     crunloop
  1055.                 movea.l   a0,a6
  1056.                 move.l    #400,d3
  1057.                 bra.b     crunit 
  1058.                                
  1059. crunjmp         movea.l   (kickchip,pc),a0
  1060.                 lea       ($f80002),a2
  1061.                 movea.l   (kickmem,pc),a1
  1062.                 cmpi.w    #$1114,(a1)
  1063.                 beq.b     crungo
  1064.                 lea       ($fc0002),a2
  1065. crungo          jmp       (a0)                
  1066.  
  1067. crunmmu         movea.l   (4).w,a0
  1068.                 movea.l   a0,a1
  1069.                 lea       ($2000,a1),a1
  1070. ..loop          clr.l     (a0)+
  1071.                 cmpa.l    a0,a1
  1072.                 bge.b     ..loop
  1073.                 moveq     #0,d0
  1074.                 move.l    d0,(4).w
  1075.                 move.l    d0,(0).w
  1076.                 movec     d0,cacr
  1077.                 movec     d0,tc
  1078.                 nop
  1079.                 cpusha    bc
  1080.                 cinva     bc       
  1081.                 pflusha                            
  1082.                 nop
  1083.                 moveq     #19,d0
  1084. .loopled        move.l    #$3fff,d1
  1085.                 bchg      #1,($bfe001)
  1086. .led            dbf       d1,.led
  1087.                 dbf       d0,.loopled
  1088.                 move.l    #$c000,d0
  1089.                 movec     d0,tc
  1090.                 movec     d6,dtt0
  1091.                 jmp       (a2)
  1092.                 nop
  1093.                 nop
  1094. crunend         nop
  1095.                 
  1096. ;************************
  1097. ;Return various registers
  1098. ;************************                
  1099.  
  1100. getregs         movec     tc,d0                 ;traslation control
  1101.                 movec     urp,d1                ;user root pointer
  1102.                 movec     cacr,d2               ;cache control register
  1103.                 movec     dtt0,d3               ;data transparaent translation 0
  1104.                 movec     dtt1,d4               ;data transparaent translation 1
  1105.                 movec     itt0,d5               ;ins transparaent translation 0
  1106.                 movec     itt1,d6               ;ins transparaent translation 1
  1107.                 movec     vbr,d7
  1108.                 movec     srp,a0
  1109.                 rte             
  1110.                 
  1111. flushcaches     suba.l    a0,a0                 ;clear a0
  1112.                 moveq     #-1,d0                ;length = all
  1113.                 moveq     #0,d1                 ;clear d1
  1114.                 or.l      #CACRF_ClearI|CACRF_ClearD,d1  ;both ins & data
  1115.                 JMPEXEC   CacheClearE           ;flush 'em
  1116.                                 
  1117.                 
  1118. getmttx         movec     dtt0,d0
  1119.                 movec     dtt1,d1
  1120.                 movec     itt0,d2
  1121.                 movec     itt1,d3
  1122.                 rte             
  1123.                 
  1124. ;*********************************************************
  1125. ;This routine will test if the MMU set-up is ours, if so
  1126. ;it will extract our structure from the invalid descriptor
  1127. ;and remove the MMU set-up, restore it the way it was and
  1128. ;free up all the resources.
  1129. ;*********************************************************
  1130.  
  1131. removefr        lea       (testcode,pc),a5      ;go and see if MMU is ours
  1132.                 CALLEXEC  Supervisor
  1133.                 tst.l     d0                    ;is it? (struct returned in a4)
  1134.                 beq.b     .oursison
  1135.                 bpl.w     prnorom
  1136.                 cmpi.l    #'FAST',(fr_id,a4)
  1137.                 beq.w     remerr
  1138.                 bra.w     testerr
  1139. .oursison       move.l    (fr_dtt0,a4),d2       ;get old dtt0 value 
  1140.                 move.l    (fr_dtt1,a4),d3       ;get old dtt1 value
  1141.                 move.l    (fr_itt0,a4),d4       ;get old itt0 value
  1142.                 move.l    (fr_itt1,a4),d5       ;get old itt1 value
  1143.                 moveq     #0,d0                 ;se the bits as off
  1144.                 move.l    d0,d1                 ;clear the mask
  1145.                 or.l      #CACRF_EnableI|CACRF_EnableD,d1     ;set the mask bits
  1146.                 CALLEXEC  CacheControl          ;turn them off
  1147.                 bsr.w     flushcaches           ;and flush 'em
  1148.                 lea       (restoremmu,pc),a5    ;replace old values
  1149.                 JSREXEC   Supervisor
  1150.                 JSREXEC   Disable               ;shut down till fastrom is gone!
  1151.                 lea       (removemmu,pc),a5     ;go remove MMU set-up
  1152.                 JSREXEC   Supervisor
  1153.                 JSREXEC   Enable                ;all OK if we're still here
  1154.                 move.l    (fr_table1,a4),(table1)  
  1155.                 move.l    (fr_table2,a4),(table2)  
  1156.                 move.l    (fr_table3,a4),(table3)  
  1157.                 move.l    (fr_table4,a4),(table22) 
  1158.                 move.l    (fr_table5,a4),(table23) 
  1159.                 move.l    (fr_kickmem,a4),(kickmem)
  1160.                 bsr.w     freetab6              ;go free all memory
  1161.                 moveq     #0,d0                 ;se the bits as off
  1162.                 or.l      #CACRF_EnableI|CACRF_EnableD,d0  ;set the mask bits
  1163.                 move.l    d0,d1                 ;clear the mask
  1164.                 CALLEXEC  CacheControl          ;turn them on
  1165.                 move.l    #remstr,-(sp)         ;tell 'em we removed it OK
  1166. printstr        lea       (credstr,pc),a0       ;print the credits
  1167.                 Printf
  1168.                 bra.w     nobuff                ;bye bye 
  1169.                 
  1170. ;*********************
  1171. ;Print kickrom aborted
  1172. ;*********************
  1173.  
  1174. kickabort       move.l    #opabo,-(sp)
  1175.                 bra.b     freedr
  1176.  
  1177. ;*************************
  1178. ;Print error opening drive
  1179. ;*************************
  1180.  
  1181. kickfilerr      move.l    #notkickf,-(sp)
  1182.                 bra.b     freeabs
  1183.  
  1184. ;*************************
  1185. ;Print error opening drive
  1186. ;*************************
  1187.  
  1188. kickerr         move.l    #baddrive,-(sp)
  1189.                 bra.b     freeabs
  1190.                 
  1191. ;*********************
  1192. ;Print disk read error
  1193. ;*********************
  1194.  
  1195. kick1err        move.l    #readerr,-(sp)
  1196. freedr          movea.l   (ioreq,pc),a1
  1197.                 ExitDrive
  1198. freeabs         move.l    #559592+fr_SIZEOF,d0          ;total size alloced
  1199.                 movea.l   (kickmem,pc),a1  
  1200.                 CALLEXEC  FreeMem
  1201.                 bra.b     printstr
  1202.                 
  1203. ;********************
  1204. ;Print cannot kickrom
  1205. ;********************
  1206.  
  1207. remerr          move.l    #badkick,-(sp)
  1208.                 bra.b     printstr
  1209.                 
  1210. ;**********************************
  1211. ;Print credits and unkown mmu setup
  1212. ;**********************************
  1213.  
  1214. testerr         move.l    #unkmmu,-(sp)
  1215.                 bra.b     printstr
  1216.                 
  1217. ;***************************************
  1218. ;Print credits and cannot remove fastrom
  1219. ;***************************************
  1220.  
  1221. prnorom         move.l    #norom,-(sp)
  1222.                 bra.w     printstr
  1223.                 
  1224. ;***********************
  1225. ;Print credits and usage
  1226. ;***********************
  1227.  
  1228. useprint        move.l    #usage,-(sp)
  1229.                 bra.w     printstr
  1230.                 
  1231. ;************************************************
  1232. ;Print credits and error if no PP&S card is found
  1233. ;************************************************
  1234.                 
  1235. perr            move.l    #ppserr,-(sp)
  1236.                 bra.w     printstr
  1237.  
  1238. ;************************************
  1239. ;This will turn the FASTROM settings
  1240. ;off and restore all as it was before 
  1241. ;we changed it
  1242. ;It is done in two sections because
  1243. ;some of it does not need to be done
  1244. ;on a disable and the other should.
  1245. ;************************************
  1246.  
  1247. removemmu       moveq     #0,d0
  1248.                 pflusha
  1249.                 movec     d0,tc
  1250.                 rte
  1251.                 
  1252. restoremmu      movec     d2,dtt0
  1253.                 movec     d3,dtt1
  1254.                 movec     d4,itt0
  1255.                 movec     d5,itt1
  1256.                 movec     d0,urp
  1257.                 movec     d0,srp
  1258.                 rte
  1259.                 
  1260. ;***********************************************
  1261. ;Check if the urp register is pointing to
  1262. ;our FASTROM table or something else and
  1263. ;return the result 
  1264. ;INPUT = none  RESULT = 0  our fastrom installed
  1265. ;                       1  if MMU not on
  1266. ;                       -1 MMU on but not ours
  1267. ;***********************************************
  1268.                 
  1269. testcode        movec      tc,d0                        ;get tc reg
  1270.                 tst.w      d0                           ;is MMU on?
  1271.                 beq.b      tc_err1                      ;nope! branch
  1272.                 movec      urp,d0                       ;else get urp reg
  1273.                 beq.b      tc_err                       ;exit if NULL
  1274.                 movea.l    d0,a4
  1275.                 move.l     (8,a4),d0                    ;get third entry
  1276.                 beq.b      tc_err                       ;not ours if NULL 
  1277.                 movea.l    d0,a4
  1278.                 cmpi.l     #'NICS',(fr_id,a4)           ;check for our ID
  1279.                 bne.b      tc_err                       ;not ours
  1280.                 moveq      #0,d0                        ;else set as ours
  1281.                 rte
  1282. tc_err          moveq      #-1,d0
  1283.                 rte               
  1284. tc_err1         moveq      #1,d0                
  1285.                 rte
  1286.                 
  1287. ;**********************
  1288. ;Set the dttx registers
  1289. ;**********************
  1290.                 
  1291. setdttx         movec     d0,dtt0
  1292.                 movec     d1,dtt1
  1293.                 rte
  1294.                 
  1295. ;**********************************************
  1296. ;Free memory routines for removal of FASTROM or
  1297. ;partial freeing if memory error on installing
  1298. ;**********************************************                
  1299.                 
  1300. freetab6        movea.l   (fr_struct,a4),a1
  1301.                 move.l    #fr_SIZEOF,d0
  1302.                 bsr.b     freeit
  1303. freetab5        movea.l   (table23,pc),a1
  1304.                 move.l    #16384,d0
  1305.                 bsr.b     freeit
  1306. freetab4        movea.l   (table22,pc),a1
  1307.                 move.l    #512,d0
  1308.                 bsr.b     freeit
  1309. freetab3        movea.l   (table3,pc),a1
  1310.                 move.l    #16384,d0
  1311.                 bsr.b     freeit
  1312. freetab2        movea.l   (table2,pc),a1
  1313.                 move.l    #512,d0
  1314.                 bsr.b     freeit
  1315. freetab1        movea.l   (table1,pc),a1
  1316.                 move.l    #512,d0
  1317.                 bsr.b     freeit
  1318. freekick        movea.l   (kickmem,pc),a1
  1319.                 move.l    #524288,d0
  1320. freeit          CALLEXEC  FreeMem
  1321.                 rts
  1322.                 
  1323. ;**********************************
  1324. ;Error string handling and printing
  1325. ;**********************************
  1326.  
  1327. mem7err         lea       (strstruct,pc),a0
  1328.                 bsr.b     dofree
  1329.                 bra.b     freetab5
  1330.  
  1331. mem6err         bsr.b     dotrans
  1332.                 bra.b     freetab4
  1333.  
  1334. mem5err         bsr.b     dotrans
  1335.                 bra.b     freetab3
  1336.  
  1337. mem4err         bsr.b     dotrans
  1338.                 bra.b     freetab2
  1339.  
  1340. mem3err         bsr.b     dotrans
  1341.                 bra.b     freetab1
  1342.  
  1343. mem2err         bsr.b     dotrans
  1344.                 bra.b     freekick
  1345.  
  1346. mem1err         lea       (strkick,pc),a0
  1347.                 
  1348. dofree          move.l    a0,-(sp)
  1349.                 lea       (memstr,pc),a0                
  1350.                 bsr.b     steprintf
  1351.                 movea.l   (sp)+,a0
  1352.                 bra.b     printit
  1353.  
  1354. dotrans         lea       (strtrans,pc),a0
  1355.                 bsr.b     dofree
  1356.                 rts
  1357.                 
  1358. steprintf       Printf
  1359.                 rts
  1360.  
  1361. ourfastrom      lea       (ourrom,pc),a0
  1362.                 bra.b     printit       
  1363.  
  1364. mmuerr          lea       (mmustr,pc),a0
  1365.                 bra.b     printit       
  1366. cpuerr          lea       (cpustr,pc),a0
  1367.                 bra.b     printit
  1368.  
  1369. vererr          lea       (verstr,pc),a0
  1370. printit         move.l    a0,-(sp)
  1371.                 lea       (credstr,pc),a0
  1372.                 bsr.b     steprintf
  1373.                 tst.l     (table1,pc)
  1374.                 beq.b     nobuff
  1375.                 lea       (kickstr,pc),a0
  1376.                 lea       (kickmem,pc),a1
  1377.                 bsr.b     steprintf
  1378.                 lea       (infostr,pc),a0
  1379.                 lea       (table1,pc),a1
  1380.                 bsr.b     steprintf
  1381.                 movea.l   (datstr,pc),a0
  1382.                 bsr.b     steprintf
  1383.                 movea.l   (insstr,pc),a0
  1384.                 bsr.b     steprintf
  1385. nobuff          move.l    (sp),d0
  1386.         cmp.l     #unkmmu,d0
  1387.         blt.b     .skip
  1388.         cmp.l     #memstr,d0
  1389.         bgt.b     .skip
  1390.         lea       (error,pc),a0
  1391.         bsr       steprintf
  1392. .skip           movea.l   (sp)+,a0
  1393.         bra       steprintf
  1394.                 
  1395.                 
  1396. ;************************************************************
  1397. ;We have to be careful here, we came here if we have found 
  1398. ;that we are not running under 2.0x.  We maybe illegal but 
  1399. ;we might also be a kick'ed rom 1.3 or 1.2 and they are 
  1400. ;asking us to do a FASTROM.  Firstly exec probably is not 
  1401. ;aware of the 68040.  We make sure we have a 68040 then we 
  1402. ;will check the MMU set up for our magic kickrom id.  As we 
  1403. ;need the mmu urp register, and that instruction is 68040 
  1404. ;specific, we may aswell use that to test for 68040 presence.
  1405. ;The movec instruction will always except to the trap code
  1406. ;but if we are on a 68040 the exception will be a privilege
  1407. ;violation else it will be an illegal instruction.
  1408. ;If all is OK, we copy the entire kickstart and atc entries
  1409. ;over into an allocated fast ram area, then modify the
  1410. ;necessary atc entries for this new ram area, kill the
  1411. ;current set up, turn on the new one and add the used chip
  1412. ;memory to the meg boundary to exec.
  1413. ;************************************************************
  1414.  
  1415. check4kick      move.l    #$8000,(dcaches)
  1416.                 movea.l   (_TaskBlock),a0               ;get our task
  1417.                 move.l    (TC_TRAPCODE,a0),-(sp)        ;save trap code
  1418.                 move.l    #test040,(TC_TRAPCODE,a0)     ;patch ours in
  1419.                 movec     urp,d0                        ;do 68040 instruction
  1420.                 move.l    (sp)+,(TC_TRAPCODE,a0)        ;replace trap code
  1421.                 tst.l     d0                            ;test result
  1422.                 beq.w     vererr                        ;error, we're illegal 
  1423.                 tst.w     d1                            ;check if MMU is on
  1424.                 bpl.w     vererr                        ;if not we're illegal
  1425.                 movea.l   (4).w,a6                      ;get execbase
  1426.                 move.w    (AttnFlags,a6),d1             ;get the attn flags
  1427.                 bset      #AFB_68040,d1                 ;set for 68040
  1428.                 bset      #AFB_FPU40,d1                 ;set for 040 FPU
  1429.                 bset      #AFB_68030,d1                 ;and for 68030
  1430.                 move.w    d1,(AttnFlags,a6)             ;and put back
  1431.                 movea.l   d0,a0                         ;make a copy of urp
  1432.                 tst.l     (8,a0)                        ;test for a third ptr
  1433.                 beq.w     vererr                        ;skip if null
  1434.                 movea.l   (8,a0),a0                     ;else get third ptr
  1435.                 cmpi.l    #'KICK',(fr_id,a0)            ;look for our id
  1436.                 bne.w     vererr                        ;skip out if not kickrom
  1437.                 move.l    (fr_kickmem,a0),d3
  1438. dochipkick      move.l    #559592+fr_SIZEOF,d0          ;total size needed
  1439.                 move.l    #MEMF_FAST,d1                 ;need fast memory
  1440.                 move.l    #32768,d2                     ;32k boundary
  1441.                 AllocAligned                            ;get aligned memory
  1442.                 tst.l     d0                            ;test result
  1443.                 beq.w     mem1err                       ;out on error
  1444.                 move.l    d0,(kickmem)                  ;we just put it there
  1445.                 movea.l   d0,a1                         ;copy dest ram
  1446.                 move.l    #$7fff,d0                     ;(512k/16)-1 loop count
  1447.                 lea       ($f80000),a0                  ;ROM kickstart address
  1448. ..turbocopy     move16    (a0)+,(a1)+                   ;16 bytes at a time
  1449.                 dbf       d0,..turbocopy                ;loop till done
  1450.                 
  1451.                 move.l    #35304+fr_SIZEOF,d0           ;remainder (-512k)
  1452.                 movea.l   d3,a0
  1453.                 lea       ($80000,a0),a0
  1454.                 movea.l   a0,a2                         ;make a copy 
  1455.                 lea       (a2,d0.l),a2                  ;calc end address
  1456.                 movea.l   (kickmem,pc),a1               ;get new block
  1457.                 lea       ($80000,a1),a1                ;calc end address
  1458. ..loop          move.l    (a0)+,(a1)+                   ;move it over 
  1459.                 cmpa.l    a0,a2                         ;finished?
  1460.                 bpl.b     ..loop                        ;nope! more yet
  1461.                 
  1462.                 move.l    (kickmem,pc),d0               ;set up all the
  1463.                 addi.l    #524288,d0                    ;pointers to each
  1464.                 move.l    d0,(table1)                   ;table1
  1465.                 move.l    #512,d1
  1466.                 add.l     d1,d0                       
  1467.                 move.l    d0,(table2)                   ;table2
  1468.                 add.l     d1,d0                       
  1469.                 move.l    d0,(table3)                   ;table3
  1470.                 addi.l    #16384,d0
  1471.                 move.l    d0,(table22)                  ;table2/2
  1472.                 add.l     d1,d0
  1473.                 move.l    d0,(table23)                  ;table2/3
  1474.                 addi.l    #16384,d0                     ;last on is our struct
  1475.                 movea.l   d0,a4                         ;save, need it later
  1476.                 move.l    d0,(fr_struct,a4)             ;save it
  1477.                 move.l    (table23,pc),(fr_table5,a4)   ;fill
  1478.                 move.l    (table22,pc),(fr_table4,a4)   ;er
  1479.                 move.l    (table3,pc),(fr_table3,a4)    ;up
  1480.                 move.l    (table2,pc),(fr_table2,a4)    ;please
  1481.                 move.l    (table1,pc),(fr_table1,a4)
  1482.                 move.l    (kickmem,pc),(fr_kickmem,a4)
  1483.                 move.l    #'FAST',(fr_id,a4)            ;our id
  1484.                 movea.l   (table3,pc),a1                ;third level
  1485.                 move.l    d3,d0
  1486.                 moveq     #11,d1
  1487.                 lsr.l     d1,d0
  1488.                 lea       (a1,d0.l),a1
  1489.                 move.l    #$f00000,d1
  1490.                 sub.l     d3,d1
  1491.                 moveq     #63,d0                        ;512k to remap = 64
  1492. ..dokickm       sub.l     d1,(a1)+                      ;convert to same address
  1493.                 dbf       d0,..dokickm                  ;till done
  1494.                 
  1495.                 movea.l   (table3,pc),a0                ;third level
  1496.                 lea       ($1f00,a0),a0                 ;$f80000 mapping
  1497.                 moveq     #63,d0                        ;64 to do
  1498.                 move.l    (kickmem,pc),d1               ;get new block
  1499.                 or.l      #$405,d1                      ;or in types
  1500. ..dotable33     move.l    d1,(a0)+                      ;and map it new area
  1501.                 addi.l    #$2000,d1                     ;each is 8k
  1502.                 dbf       d0,..dotable33                ;till done
  1503.                 
  1504.                 movea.l   (table1,pc),a0                ;get first table
  1505.                 move.l    (table2,pc),d0                ;get second table
  1506.                 or.b      #3,d0                         ;UDT descriptor
  1507.                 move.l    d0,(a0)+                      ;shove it in
  1508.                 move.l    (table22,pc),d0               ;get 2nd table 2
  1509.                 or.b      #3,d0                         ;UDT descriptor
  1510.                 move.l    d0,(a0)+                      ;shove it in
  1511.                 move.l    a4,(a0)                       ;link our struct on
  1512.                 movea.l   (table2,pc),a0                ;get table 2
  1513.                 move.l    (table3,pc),d2                ;get table 3
  1514.                 moveq     #127,d0                       ;128 entries
  1515.                 or.l      #3,d2                         ;UDT descriptor 
  1516. ..dotable2      move.l    d2,(a0)+                      ;move one in
  1517.                 addi.l    #128,d2                       ;add next address
  1518.                 dbf       d0,..dotable2                 ;loop till done
  1519.                 
  1520.                 CALLEXEC  Disable                       ;implies Forbid
  1521.                 movea.l   (table1,pc),a2                ;get table start
  1522.                 move.l    a2,(urpreg)                   ;load print var
  1523.                 move.l    a2,(srpreg)                   ;load print var
  1524.                 move.l    #inson,(insstr)               ;load print var
  1525.                 move.l    #daton,(datstr)               ;load print var
  1526.                 cmpi.l    #$80008000,(dcaches,pc)       ;all caches on?
  1527.                 beq.b     .callon                       ;skip if so
  1528.                 move.l    #datoff,(datstr)              ;else change print var
  1529. .callon         lea       (chipfast,pc),a0              ;tell we're changing it
  1530.                 Printf
  1531.                 lea       (changemmu,pc),a5             ;get main code
  1532.                 CALLEXEC  Supervisor                    ;go do it
  1533.                 JSREXEC   Enable                        ;turn it all back on
  1534.                 move.l    #MEMF_PUBLIC,d1
  1535.                 moveq     #12,d0
  1536.                 JSREXEC   AllocMem
  1537.                 tst.l     d0
  1538.                 beq.b     .skpname
  1539.                 movea.l   d0,a1
  1540.                 lea       (memname,pc),a0
  1541. ..copname       move.b    (a0)+,(a1)+
  1542.                 bne.b     ..copname
  1543.                 movea.l   d0,a1
  1544. .skpname        JSREXEC   Forbid
  1545.         movea.l   d3,a0                ;set base address
  1546.                 move.l    d3,d1                         ;make a copy
  1547.                 andi.l    #$fffff,d1                    ;clear any leading 1
  1548.                 move.l    #$100000,d0                   ;a meg boundary
  1549.                 sub.l     d1,d0                         ;less d1 = size to bound
  1550.                 move.l    #MEMF_CHIP|MEMF_PUBLIC|MEMF_LOCAL|MEMF_24BITDMA,d1                 ;its chip
  1551.                 moveq     #-10,d2                       ;chip priority -10
  1552.                 pushregs                  ;save regs
  1553.                 movea.l   (4).w,a6                      ;get exec
  1554.                 movea.l   (MemList,a6),a2               ;get the memlist
  1555. .doloop         cmp.l     (MH_UPPER,a2),d3              ;get the upper bound
  1556.         bne.b     .incit                        ;if not ours then inc
  1557.         cmp.w     (MH_ATTRIBUTES,a2),d1         ;are the atts equal
  1558.                 bne.b     .doadd                        ;addmemlist if not
  1559.                 add.l     d0,d3                         ;calc upper
  1560.                 move.l    d3,(MH_UPPER,a2)              ;change upper bound
  1561.                 movea.l   (MH_FIRST,a2),a3              ;get the MC struct
  1562. ..loop1         tst.l     (MC_NEXT,a3)                  ;last one?
  1563.                 beq.b     .gotlast                      ;yep branch
  1564.                 movea.l   (MC_NEXT,a3),a3               ;get next 
  1565.                 bra.b     ..loop1                       ;and loop
  1566. .gotlast        add.l     d0,(MC_BYTES,a3)              ;add mem to chunk
  1567.         add.l     d0,(MH_FREE,a2)               ;and to total
  1568.                 bra.b     .finadd                       ;and exit
  1569. .incit          movea.l   (LN_SUCC,a2),a2               ;get next
  1570.                 tst.l     (a2)                          ;last ?
  1571.                 bne.b     .doloop                       ;nope! loop
  1572.                 bra.b     .finadd                       ;yep! finish
  1573. .doadd          JSREXEC   Permit
  1574.         popregs
  1575.         JSREXEC   AddMemList                    ;add the memory
  1576.         bra.b     .xitadd
  1577. .finadd         JSREXEC   Permit
  1578.         popregs
  1579. .xitadd        lea       (fastinst,pc),a0              ;get all done string
  1580.                 bra.w     printit                       ;and exit
  1581.                 
  1582. ;*************************************
  1583. ;At this point the chiprom OS is alive
  1584. ;and we are going to change it over to
  1585. ;the fastrom setup.  We flush all atc
  1586. ;entries and all caches, so that any
  1587. ;references to the chip OS are gone.
  1588. ;************************************
  1589.                 
  1590. changemmu       moveq     #0,d0                         ;set for caches off
  1591.                 movec     d0,cacr                       ;turn the caches off
  1592.                 movec     d0,tc                         ;turn MMU off
  1593.                 nop
  1594.                 pflusha                                 ;invalidate all ATC
  1595.                 cpusha    bc                            ;flush all caches
  1596.                 cinva     bc                            ;inavalidate all
  1597.                 nop
  1598.                 movec     dtt0,d0                       ;get dtt0
  1599.                 move.l    d0,(dt0)                      ;set print var
  1600.                 movec     dtt1,d0                       ;get dtt1
  1601.                 move.l    d0,(dt1)                      ;set print var
  1602.                 movec     itt0,d0                       ;get itt0 
  1603.                 move.l    d0,(it0)                      ;set print var
  1604.                 movec     itt1,d0                       ;get itt1
  1605.                 move.l    d0,(it1)                      ;set print var
  1606.                 movec     vbr,d0                        ;get vbr
  1607.                 move.l    d0,(vbreg)                    ;set print var
  1608.                 movec     a2,urp                        ;set new urp
  1609.                 movec     a2,srp                        ;and srp
  1610.                 move.l    #$c000,d0                     ;mmu on 8k pages
  1611.                 move.w    d0,(tcreg)                    ;set print var
  1612.                 movec     d0,tc                         ;MMU on
  1613.                 move.l    (dcaches,pc),d0               ;cache settings
  1614.                 movec     d0,cacr                       ;set caches
  1615.                 rte                                     ;finished
  1616.                 
  1617. ;**********************************************
  1618. ;This is the trapcode handler to check if we 
  1619. ;have a 68040 in the system.  The instruction
  1620. ;used before always gave an exception and will
  1621. ;come here.  We get the supplied exception from
  1622. ;the stack and we check if it is a privilege
  1623. ;violation, if so we have a 68040 and we return 
  1624. ;the URP in D0, and TC in D1, else we return 
  1625. ;NULL in D0.
  1626. ;**********************************************               
  1627.                 
  1628. test040         move.l    (sp)+,d0                      ;get Amiga exception
  1629.                 cmpi.w    #8,d0                         ;privilege violation?
  1630.                 bne.b     .not040                       ;skip if not
  1631.                 movec     urp,d0                        ;get the urp reg
  1632.                 movec     tc,d1
  1633. .trapxit        addq.l    #4,(2,sp)                     ;skip movec instruction
  1634.                 rte                                     ;return from exeption
  1635. .not040         moveq     #0,d0                         ;clear return reg
  1636.                 bra.b     .trapxit                      ;and exit
  1637.  
  1638. ;**********************************************
  1639. ;This routine will manipulate a register on the 
  1640. ;PP&S 68040 card so that the next boot will
  1641. ;switch to the required processor.  The choice
  1642. ;to switch or abort is done via the V2.04 
  1643. ;function, EasyRequestArgs.
  1644. ;**********************************************
  1645.  
  1646. doswitch        lea       ($800c000),a2                 ;address of PP&S register
  1647.                 move.l    #68040,(from)                 ;set data for RDF string
  1648.                 move.l    #68030,(to)                   ;set data for RDF string
  1649.                 move.b    (a2),d0                       ;get a byte
  1650.                 not.b     d0                            ;invert it
  1651.                 beq.b     .mode030                      ;if zero we're in 68040
  1652.                 move.l    #68030,(from)                 ;set data for RDF string
  1653.                 move.l    #68040,(to)                   ;set data for RDF string
  1654. .mode030        move.l    d0,d2                         ;save current mode
  1655.                 move.l    #from,d0                      ;get data for RDF string
  1656.                 clr.l     (esidcmp)
  1657.                 bsr.b     requester                     ;do the EasyRequestArgs
  1658.                 tst.l     d0                            ;which gadget?
  1659.                 beq.b     .dsexit                       ;abort
  1660.                 tst.b     d2
  1661.                 beq.b     .do030
  1662.                 move.l    #-1,(a2)                      ;set for 68040
  1663.                 move.l    #-1,(a2)                      ;push it twice
  1664.                 cmpi.b    #-1,(a2)                      ;read it byte! did it set?
  1665.                 beq.b     .pok                          ;PP&S is here!
  1666. .pperr          bra.w     perr                          ;else they dunna got one
  1667. .do030          move.l    (a2),d2                       ;save current mode
  1668.                 move.l    #$fefefefe,(a2)               ;set for 68030
  1669.                 move.l    #$fefefefe,(a2)               ;set long
  1670.                 cmpi.b    #$fe,(a2)                     ;check read byte
  1671.                 bne.b     .pperr                        ;if not no PP&S here!
  1672. .pok            lea       (easyreq,pc),a0               ;else get easy struct
  1673.                 move.l    #esabort,(es_GadgetFormat,a0) ;change the gadgets
  1674.                 move.l    #esboot,(es_TextFormat,a0)    ;and the the text
  1675.                 moveq     #0,d0                         ;no data
  1676.                 move.l    d0,(esidcmp)
  1677.                 bsr.b     requester                     ;will not come back
  1678.                                                         ;unless they aborted
  1679.                 move.l    d2,($800c000)                 ;set old value back
  1680.                 bsr.w     flushcaches                   ;flush em
  1681. .dsexit         lea       (credstr,pc),a0
  1682.                 bsr.b     .prntf
  1683.                 lea       (opabo,pc),a0                 ;get aborted string
  1684. .prntf          Printf                                  ;print it
  1685.                 rts                                     ;and we're gone..
  1686.                 
  1687.                 
  1688. ;******************
  1689. ;Call the requester
  1690. ;******************                    
  1691.                 
  1692. requester       movem.l  a2-a3,-(sp)                    ;save non scratch
  1693.                 suba.l   a0,a0                          ;WB window
  1694.                 lea      (easyreq,pc),a1                ;easy struct
  1695.                 lea      (esidcmp,pc),a2                ;null ext idcmp 
  1696.                 movea.l  d0,a3                          ;data for string
  1697.                 CALLINT  EasyRequestArgs                ;do requester
  1698.                 movem.l  (sp)+,a2-a3                    ;pop 'em
  1699.                 rts                                     ;and return
  1700.                 
  1701. ;********************************
  1702. ;Data section
  1703. ;Don't change the order of any
  1704. ;vars, some print routines expect
  1705. ;them in this order.
  1706. ;********************************
  1707.                 
  1708.                 include "/set040/set040.i"              ;structure definitions
  1709.                
  1710. ioreq           dc.l      0
  1711. kickchip        dc.l      0
  1712. kickname        dc.l      0
  1713. from            dc.l      0
  1714. to              dc.l      0
  1715. _stdout         dc.l      0                
  1716. kickmem         dc.l      0
  1717. table1          dc.l      0
  1718. table2          dc.l      0
  1719. table3          dc.l      0
  1720. it0             dc.l      0
  1721. it1             dc.l      0
  1722. dt0             dc.l      0
  1723. dt1             dc.l      0
  1724. urpreg          dc.l      0
  1725. srpreg          dc.l      0
  1726. vbreg           dc.l      0
  1727. tcreg           dc.w      0
  1728. table22         dc.l      0
  1729. table23         dc.l      0
  1730. zcache          dc.b      0
  1731. mbspace         dc.b      0
  1732. scrtit          dc.b      0
  1733. noclick         dc.b      0
  1734. kickflag        dc.b      0
  1735. kludge          dc.b      0
  1736. datstr          dc.l      daton
  1737. insstr          dc.l      inson
  1738. dcaches         dc.w      $8000
  1739. icaches         dc.w      $8000
  1740. z3var1          dc.l      $4fbc020
  1741. z3var0          dc.l      $8f7c020
  1742. ver        dc.b      '$VER: Set040 1.14 (15.3.92)',0
  1743. tdname          dc.b      'trackdisk.device',0
  1744. credstr         dc.b      $0a,$1b,'[1;33m',$1b,'[4mSet040 V1.14 ',$1b,'[31m',$1b,'[4mWritten in Assembler by Nic Wilson',$1b,'[0m',$0a,$0a,0
  1745. infostr         dc.b      'Level A ->',$1b,'[0;32m$%lx ',$1b,'[0mLevel B ->',$1b,'[0;32m$%lx',$1b,'[0m Level C ->',$1b,'[0;32m$%lx',$0a,$0a
  1746.                 dc.b      $1b,'[0mITT0 ->',$1b,'[32m$%-8.lx',$1b,'[0m ITT1 ->',$1b,'[32m$%-8.lx ',$1b,'[0m',$0a
  1747.                 dc.b      'DTT0 ->',$1b,'[32m$%-8.lx',$1b,'[0m DTT1 ->',$1b,'[32m$%-8.lx',$1b,'[0m',$0a
  1748.                 dc.b      'URP  ->',$1b,'[32m$%-8.lx',$1b,'[0m SRP  ->',$1b,'[32m$%-8.lx',$1b,'[0m',$0a
  1749.                 dc.b      'VBR  ->',$1b,'[32m$%-8.lx',$1b,'[0m TC   ->',$1b,'[32m$%-4.x',$1b,'[0m',$0a,0
  1750. usage           dc.b      $0a,'USAGE-> ',$1b,'[0;33mSet040 <switch> (only one ',"'-'",' switch is permitted).',$0a
  1751.                 dc.b      $1b,'[0;33m',TAB,'If no switch is supplied, the current setup will be displayed,',$0a
  1752.                 dc.b      TAB,'and if a CHIPROM setup is found, it will be changed to FASTROM ',$1b,'[0m',$0a
  1753.                 dc.b      $1b,'[0;32m-f<args>  = install FASTROM with optional parameters (EG. -fzi).',$1b,'[0m',$0a
  1754.                 dc.b      $1b,'[0;33m',TAB,'If no arguments are supplied, a default FASTROM will be installed.',$1b,'[0m',$0a
  1755.                 dc.b      TAB,'z = allow caching of ZorroII memory space ($200000 - $A00000).',$0a
  1756.                 dc.b      TAB,'w = set ($1000000 - $3FFFFFF) as Writethrough.',$0a
  1757.                 dc.b      TAB,'c = set ($4000000 - $FFFFFFF) as Writethrough.',$0a
  1758.                 dc.b      TAB,'d = do not enable data cache.',$0a
  1759.                 dc.b      TAB,'i = do not enable instruction cache.',$0a
  1760.                 dc.b      TAB,'t = do not change Workbench screen title.',$0a
  1761.                 dc.b      TAB,'n = patch to stop floppy drives clicking.',$0a
  1762.                 dc.b      $1b,'[0;32m-k <file> = Load, install and boot a different kickstart',$1b,'[0m',$0a
  1763.                 dc.b      '   <file> = Path and filename to kickstart file (1.2 - 2.0).',$0a
  1764.                 dc.b      TAB,'    For loading from Kickstart or SuperKickstart disk,',$0a
  1765.                 dc.b      TAB,'    use floppy drive name for <file> (EG. Set040 -k DF0:).',$0a
  1766.                 dc.b      $1b,'[0;32m-c<args>  = manipulate caches as per options (EG. -cIdC).',$1b,'[0m',$0a
  1767.                 dc.b      TAB,'I = Enable  Instruction Cache.',$0a
  1768.                 dc.b      TAB,'i = Disable Instruction Cache.',$0a
  1769.                 dc.b      TAB,'D = Enable  Data Cache.',$0a
  1770.                 dc.b      TAB,'d = Disable Data Cache.',$0a
  1771.                 dc.b      TAB,'B = Enable  Both Caches.',$0a
  1772.                 dc.b      TAB,'b = Disable Both Caches.',$0a
  1773.                 dc.b      TAB,'A = Enable  Both Caches & Copyback ($4000000 - $FFFFFFF).',$0a
  1774.                 dc.b      TAB,'a = Disable Both Caches & Copyback ($4000000 - $FFFFFFF).',$0a
  1775.                 dc.b      TAB,'C = Enable  Copyback ($4000000 - $FFFFFFF).',$0a
  1776.                 dc.b      TAB,'c = Disable Copyback ($4000000 - $FFFFFFF).',$0a
  1777.                 dc.b      $1b,'[0;32m-r',TAB,'  = remove FASTROM & reclaim resources.',$1b,'[0m',$0a
  1778.                 dc.b      $1b,'[0;32m-s',TAB,'  = Switch CPU 68040-><-68030 (PP&S A3000 Card Only)',$1b,'[0m',$0a,0
  1779. usage1          dc.b      'For usage, type -> ',$1b,'[32mSet040 ?',$1b,'[0m',$0a,0
  1780. kickstr         dc.b      $1b,'[0mKickstart physical address ->',$1b,'[32m$%lx',$1b,'[0m',$0a,0
  1781. daton           dc.b      'DATA CACHE ENABLED  ',0
  1782. datoff          dc.b      'DATA CACHE DISABLED ',0
  1783. inson           dc.b      'INST CACHE ENABLED  ',$0a,$0a,0
  1784. insoff          dc.b      'INST CACHE DISABLED ',$0a,$0a,0
  1785. fastinst        dc.b      'FASTROM is installed. ',$0a,0                         
  1786. kickinst        dc.b      'KICKROM is installed. ',$0a,0                         
  1787. remstr          dc.b      $0A,'FASTROM removed OK!',$0a,0                         
  1788. error        dc.b      'ERROR -> ',0
  1789. unkmmu          dc.b      'UNKNOWN MMU SETUP!!',$0a,0                         
  1790. badkick         dc.b      'CANNOT REMOVE A KICKROM SETUP!',$0a,0
  1791. ourrom          dc.b      'FASTROM already installed!',$0a,0                         
  1792. norom           dc.b      'FASTROM not installed!',$0a,0                         
  1793. verstr          dc.b      'AmigaDOS V2.04 (V37) or greater required.',$0a,0                         
  1794. cpustr          dc.b      'A 68040 CPU is not installed in this system.',$0a,0                             
  1795. mmustr          dc.b      'MMU already in use, I cannot install FASTROM/KICKROM.',$0a,0                            
  1796. ppserr          dc.b      'A PP&S A3000 card must be installed.',0
  1797. baddrive        dc.b      'Opening drive.',$0a,0
  1798. readerr         dc.b      'That disk was not a kickstart disk.',$0a,0
  1799. notkickf        dc.b      'File is not a kickstart file.',$0a,0
  1800. memstr          dc.b      'Could not get memory for '
  1801. strkick         dc.b      'KickStart.',$0a,0                       
  1802. strtrans        dc.b      'translation tables.',$0a,0                       
  1803. strstruct       dc.b      'structure.',$0a,0                       
  1804. chipfast        dc.b      $0A,'Converting CHIPROM to FASTROM',$0a,0                       
  1805. patch           dc.b      'Patching Kickstart to stop MMU being disabled',0
  1806. opabo           dc.b      'Operation aborted.',$0a,0
  1807. memname         dc.b      'chip memory',0
  1808.                 
  1809.                 END
  1810.                           
  1811.